<template>
  <el-container class="layout-container">
    <el-aside class="side-nav" :width="isCollapse ? '1.5vw' : '25vw'">
      <div class="collapse-button">
        <el-tooltip v-if="!isPortrait" :content="isCollapse ? '点击展开侧边栏' : '点击隐藏侧边栏'" placement="right">
          <el-button type="text" @click="toggleCollapse">
            <el-icon :size="45">
              <component :is="isCollapse ? 'ArrowRight' : 'ArrowLeft'"/>
            </el-icon>
          </el-button>
        </el-tooltip>
        <el-button v-else type="text" @click="toggleCollapse">
          <el-icon :size="45">
            <component :is="isCollapse ? 'ArrowRight' : 'ArrowLeft'"/>
          </el-icon>
        </el-button>
      </div>
      <el-menu
          :default-active="$route.path"
          active-text-color="#ffd04b"
          background-color="#545c64"
          router
          text-color="#fff"
      >
        <template v-for="route in menuRoutes" :key="route.path">
          <el-sub-menu v-if="route.children" :index="route.path">
            <template #title>
              <span>{{ route.meta?.title }}</span>
            </template>
            <el-menu-item
                v-for="child in route.children"
                :key="child.path"
                :index="child.path"
            >
              <span>{{ child.meta?.title }}</span>
            </el-menu-item>
          </el-sub-menu>
          <el-menu-item v-else :index="route.path">
            <span>{{ route.meta?.title }}</span>
          </el-menu-item>
        </template>
      </el-menu>
    </el-aside>
    <el-container class="main-content">
      <el-header class="header">
        <div class="header-content">
          <el-breadcrumb separator="/" class="breadcrumb">
            <el-breadcrumb-item
                v-for="(tag, index) in tags"
                :key="tag.path"
                :class="{ 'is-active': $route.path === tag.path }"
            >
              <span @click="handleTagClick(tag)">{{ tag.meta.title }}</span>
              <el-icon v-if="tags.length > 1" @click="handleTagClose(tag, index)">
                <close/>
              </el-icon>
            </el-breadcrumb-item>
          </el-breadcrumb>
          <div class="user-info">
            <span>{{ username }}</span>
            <el-button type="primary" @click="logout">退出</el-button>
          </div>
        </div>
      </el-header>
      <el-main class="content-wrapper">
        <router-view></router-view>
      </el-main>
    </el-container>
  </el-container>
</template>

<script setup>
import {computed, onMounted, ref, watch} from 'vue'
import {useRoute, useRouter} from 'vue-router'
import {ElMessage} from 'element-plus'
import {useStore} from 'vuex'
import {iget} from "@/api";

const router = useRouter()
const route = useRoute()
const store = useStore()

const isCollapse = ref(false)
const isPortrait = ref(false)

const toggleCollapse = () => {
  isCollapse.value = !isCollapse.value
}

const menuRoutes = computed(() => {
  const routes = store.getters.menuRoutes;
  const role = store.state.role;
  return routes.filter(route => {
    if (role === 'admin' && route.meta.hiddenForAdmin) {
      return false;
    }
    return true;
  });
});

const isAdmin = computed(() => store.state.role === 'admin')

let heartbeatInterval = null

const tags = ref([])

const handleTagClick = (tag) => {
  router.push(tag.path)
}

const handleTagClose = (tag, index) => {
  tags.value.splice(index, 1)
  if (route.path === tag.path) {
    const lastTag = tags.value[tags.value.length - 1]
    if (lastTag) {
      router.push(lastTag.path)
    } else {
      router.push('/dashboard')
    }
  }
}

watch(route, (newRoute) => {
  const existingTag = tags.value.find(tag => tag.path === newRoute.path)
  if (!existingTag && newRoute.meta.title) {
    tags.value.push({
      path: newRoute.path,
      meta: newRoute.meta
    })
  }
}, {immediate: true})

const fetchUserInfo = async () => {
  try {
    const token = store.getters.token
    if (!token) {
      await router.push('/')
      return
    }

    await store.dispatch('getUserinfo')
    await store.dispatch('getAcademicOrigin')
  } catch (error) {
    ElMessage.error('获取用户信息失败，请尝试刷新')
  }
}

const logout = () => {
  router.push('/')
  store.commit('logout')
}

const checkHealthy = async () => {
  try {
    const token = store.getters.token
    if (!token) return

    const response = await iget('/auth/healthy', {})
    if (response.data.code === 500) {
      ElMessage.error('账号在其他设备登录')
      logout()
    }
  } catch (error) {
    console.log("心跳检测失败" + error)
  }
}

watch(isAdmin, (newVal) => {
  if (newVal) {
    heartbeatInterval = setInterval(checkHealthy, 8000)
  } else {
    if (heartbeatInterval) {
      clearInterval(heartbeatInterval)
      heartbeatInterval = null
    }
  }
}, {immediate: true})

onMounted(() => {
  fetchUserInfo()
  if (router.currentRoute.value.path === '/home') {
    router.push('/dashboard')
  }
})
</script>

<style scoped>
.layout-container {
  height: 98vh;
  display: flex;
}

.side-nav {
  background: #58595a;
  border-radius: 8px;
  height: 98vh;
  position: relative;
  transition: width 0.3s ease;
}

.side-nav.collapsed {
  background: #ffffff;
}

.collapse-button {
  position: absolute;
  right: -20px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 9999;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
}

.collapse-button .el-button {
  color: black !important; /* 确保颜色优先级 */
  background-color: deepskyblue;
  z-index: 99999;
}

.collapse-button .el-button:hover {
  background-color: deepskyblue;
}

.header {
  background: #ffffff;
  border: 0.5px #d6d7da;
  margin: 4vh;
  padding: 1vw;
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: white;
  border-radius: 8px;
  height: 5vh;
}

.header-content {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

.breadcrumb {
  margin: 0;
}

.user-info {
  display: flex;
  align-items: center;
  gap: 10px;
}

.main-content {
  flex: 1;
  display: flex;
  flex-direction: column;
  margin: 1vh;
}

.content-wrapper {
  border: 1px #58595a;
  border-radius: 8px;
  padding: 20px;
  overflow-y: auto;
  flex: 1;
}

.breadcrumb {
  margin: 10px;
}

.breadcrumb-item {
  cursor: pointer;
}

.breadcrumb-item.is-active {
  font-weight: bold;
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.2s;
}

.fade-enter,
.fade-leave-to {
  opacity: 0;
}

@media (max-aspect-ratio: 1/1) {
  .header h3 {
    font-size: 1rem;
  }

  .user-info span {
    font-size: 0.8rem;
  }

  .el-menu-item span {
    font-size: 0.8rem;
    margin-left: 3vw;
  }

  .el-sub-menu span {
    font-size: 0.8rem;
    margin-left: 3vw;
  }

  .breadcrumb-item span {
    font-size: 0.8rem;
  }
}
</style>
